package com.zhtd.knocker.business;

import android.os.Looper;

import com.google.gson.reflect.TypeToken;
import com.zhtd.knocker.async.AsyncTask;
import com.zhtd.knocker.business.entity.BaseEntity;
import com.zhtd.knocker.business.entity.HostRequest;
import com.zhtd.knocker.business.entity.HostResponse;
import com.zhtd.knocker.business.entity.LoginCallback;
import com.zhtd.knocker.business.entity.LoginRequest;
import com.zhtd.knocker.business.entity.LoginResponse;
import com.zhtd.knocker.business.entity.QueryHostCallback;
import com.zhtd.knocker.http.HttpImpl;
import com.zhtd.knocker.http.HttpRequest;
import com.zhtd.knocker.http.ResponseBean;
import com.zhtd.knocker.util.GsonUtils;

import java.lang.ref.WeakReference;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public final class LoginService {
    /**
     * 默认连接超时时间
     */
    private static int connectTimeout = 10_000;
    /**
     * 默认读取超时时间
     */
    private static int readTimeout = 10_000;
    private static final HttpImpl HttpImpl = new HttpImpl();
    private static final AtomicInteger index = new AtomicInteger();
    private static final ConcurrentHashMap<Integer,WeakReference<AsyncTask<Void, Void, ResponseBean>>> tasks = new ConcurrentHashMap<>();

    /**
     * 设置超时时间
     *
     * @param connect 连接超时
     * @param read    读取超时
     */
    final static void setTimeout(int connect, int read) {
        connectTimeout = connect;
        readTimeout = read;
    }

    /**
     * 同步登录
     *
     * @param loginRequest 登录请求实体
     * @param url          url
     * @return 登录返回信息
     * @throws Exception 登录请求异常,通过getMessage()
     */
    public static synchronized BaseEntity<LoginResponse> login(final LoginRequest loginRequest, final String url) throws Exception {
        if (loginRequest == null || url == null) {
            return null;
        }
        String body = GsonUtils.toJSON(loginRequest);
        HttpRequest req = new HttpRequest(url, connectTimeout, readTimeout, body);
        ResponseBean responseBean = HttpImpl.doPost(req);
        if (responseBean.success()) {
            BaseEntity<LoginResponse> loginRes = GsonUtils.fromJson(responseBean.getResponse(), new TypeToken<BaseEntity<LoginResponse>>() {
            }.getType());
            return loginRes;
        } else {
            throw new Exception(responseBean.getResponse());
        }
    }

    /**
     * 同步查询主机
     *
     * @param hostRequest 查询请求实体
     * @param url         url
     * @return hostResponse
     * @throws Exception 查询请求异常,通过getMessage()
     */
    public static synchronized HostResponse queryHost(final HostRequest hostRequest, final String url) throws Exception {
        if (hostRequest == null || url == null) {
            return null;
        }
        String body = GsonUtils.toJSON(hostRequest);
        HttpRequest req = new HttpRequest(url, connectTimeout, readTimeout, body);
        ResponseBean responseBean = HttpImpl.doPost(req);
        if (responseBean.success()) {
            HostResponse res = GsonUtils.fromJson(responseBean.getResponse(), HostResponse.class);
            return res;
        } else {
            throw new Exception(responseBean.getResponse());
        }
    }

    /**
     * 异步登录(需要在UI线程中)
     *
     * @param loginRequest 登录请求实体
     * @param url          url
     * @param callback     登录回调
     */
    public static synchronized void asyncLogin(final LoginRequest loginRequest, final String url, final LoginCallback callback) {
        if (loginRequest == null || url == null || callback == null) {
            return;
        }
        Looper looper = Looper.myLooper();
        if (looper == null) {
            callback.onFailed("需要在主线程操作");
            return;
        }
        final int order = index.getAndIncrement();
        final AsyncTask<Void, Void, ResponseBean> task = new AsyncTask<Void, Void, ResponseBean>() {
            @Override
            protected ResponseBean doInBackground(Void... voids) {
                String body = GsonUtils.toJSON(loginRequest);
                final HttpRequest req = new HttpRequest(url, connectTimeout, readTimeout, body);
                ResponseBean responseBean = HttpImpl.doPost(req);
                return responseBean;
            }

            @Override
            protected void onPostExecute(final ResponseBean responseBean) {
                super.onPostExecute(responseBean);
                if (responseBean.success()) {
                    BaseEntity<LoginResponse> res = GsonUtils.fromJson(responseBean.getResponse(), new TypeToken<BaseEntity<LoginResponse>>() {
                    }.getType());
                    callback.onSuccessLogin(res);
                } else {
                    callback.onFailed(responseBean.getResponse());
                }
                WeakReference<AsyncTask<Void, Void, ResponseBean>> task = tasks.remove(order);
                task.clear();

            }
        }.execute();
        tasks.put(order,new WeakReference<AsyncTask<Void, Void, ResponseBean>>(task));
    }

    /**
     * 异步查询Host地址(需要在UI线程中)
     *
     * @param hostReq  查询请求实体
     * @param url      url
     * @param callback 查询回调
     */
    public static synchronized void asyncQueryHost(final HostRequest hostReq, final String url, final QueryHostCallback callback) {
        if (hostReq == null || url == null || callback == null) {
            return;
        }
        Looper looper = Looper.myLooper();
        if (looper == null) {
            callback.onFailed("需要在主线程操作");
            return;
        }
        final int order = index.getAndIncrement();
        final AsyncTask<Void, Void, ResponseBean> task = new AsyncTask<Void, Void, ResponseBean>() {
            @Override
            protected ResponseBean doInBackground(Void... voids) {
                String body = GsonUtils.toJSON(hostReq);
                final HttpRequest req = new HttpRequest(url, connectTimeout, readTimeout, body);
                ResponseBean responseBean = HttpImpl.doPost(req);
                return responseBean;
            }

            @Override
            protected void onPostExecute(final ResponseBean bean) {
                super.onPostExecute(bean);
                if (bean.success()) {
                    HostResponse res = GsonUtils.fromJson(bean.getResponse(), HostResponse.class);
                    callback.onSuccessQueryHost(res);
                } else {
                    callback.onFailed(bean.getResponse());
                }
                tasks.remove(order);
            }
        }.execute();
        tasks.put(order,new WeakReference<AsyncTask<Void, Void, ResponseBean>>(task));
    }

    /**
     * 退出时释放回调
     */
    public static synchronized void release(){
        if(tasks != null && tasks.size() > 0){
            for(WeakReference<AsyncTask<Void, Void, ResponseBean>> obj: tasks.values()){
                if(!obj.get().isCancelled()) {
                    obj.get().cancel(true);
                    obj.clear();
                    obj = null;
                }
            }
            tasks.clear();
        }
    }
}
